home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
SCIENTIF
/
3841.ZIP
/
RESTORE.PAS
< prev
Wrap
Pascal/Delphi Source File
|
1991-10-01
|
9KB
|
238 lines
Algorithm to read Esee Save-file
1. Determine file name/open it.
2. Abort if file size<=0 or I/O error
<all reads below done byte-wise with Pascal blockread function>
3. Determine version:
first byte=#252 for version 1.05-1.09
21 seqs x 18kb
first byte=#253 version 2.0 (soon to be released)
46 seqs x 9.5kb
Abort if one of above not found.
4. Read next two bytes=number of sequences as integer
5. For i := 1 to number of sequences get records. Check after each one
to see if there's enough memory.
6. Each record <check for i/o error after each read,
abort process if any error>:
seqlen: 2 bytes (integer)
sequence data: seqlen bytes
end-of sequence character is ascii #1 (happy face)
and it included in count
seqname:65 bytes (characters)
linesum:6 bytes (pascal real)
start :6 bytes (pascal real)
Start is the position to start numbering on print-out,
for example a sequence in a promotor may begin with a
negative number. Make sure, when counting, to avoid
position 0 since by convention it is not used.
sequence type:1 byte (an upper case character)
valid types: NPTA
numoff:1 byte (boolean) user may have set numbering off within Esee or
the program might have done (by default type A sequences have
numbering off when they are created)
reve:1 byte (boolean) has the user selected reverse (3'->5') orientation?
One scenario for this is the display of double stranded DNA. The lower
sequence is created by complementing, followed by reverse.
+_+_+_+_+_+_+_+_+_+_+_+_+_+_+_+_+_
Now here's a fragment of the actual code that I use.
You might want to replace some of the tests of allowable sequence
length, memory use with limits relevant to BoxShade, rather than Esee
+_+_+_++++_+_+_+++_+_+_+_+_+_+_+_+_
...
...
(*Definitions borrowed from Main program*)
(*in order to make the algorithm easier to understand*)
(*I have no idea if you understand Pascal, you're probably
in the C generation :-) *)
CONST
realseqlen=18500; (*soon to be released version 9900 *)
logo:char=#253; (*#254 in next version, allow either *)
maxseqs=21; (*46 in next version limit should be set by boxshade*)
TYPE
seqarray=array(1..realseqlen) of char;
seqrec=record
seqlen:integer; (*total seqlen ... others to follow*)
sarr:seqarray;
name:string[64]; linesum,start:real;
kind:char; NUMOFF,reve:BOOLEAN
end; (*seqrec*)
seqpoint=^seqrec;
VAR
stamp:byte;
spnt:array[1..nseqs] of seqpoint;
inname:string;
rfile:file; (*untyped file*)
nseq,ierr:integer;
Procedure Flash; (*just a fancey prompt message*)
begin end;
Procedure Insrept; (*clear flashed message*)
begin end;
Procedure Emesg; (*flash an error message*)
begin end;
(*a given sequence record can be addressed as follows:
spnt[1]^.sarr[1] is the first character of the first sequence *)
(* you can also use:
with spnt[i]^ do
begin
sarr[1]:=1;
kind:='P'
end;
*)
Procedure Restore;
var rseq,rs,i:integer; (*restore*)
needed:word; namelen:byte; logic:boolean;
Procedure Fadeout; (*tidy up if restore fails*)
begin end;
procedure getrecord;
var j:byte; tempname:string[64];
begin (*getrecord*)
with spnt[rs]^ do
begin
(*$i-*)
ierr:=1; (*only a succesful read sets it to 0*)
fillchar(sarr,realseqlen,dot);
blockread(rfile,seqlen,2);
if ioresult<>0 then exit;
(*fix for long old save files*)
if seqlen>maxseqlen
then begin
blockread(rfile,sarr,maxseqlen);
sarr[maxseqlen]:=#1;
blockread(rfile,temp,seqlen-maxseqlen);
(*put overflow in temp to throw away*)
(* say 18,000 - 9499 = 8500 so temp should be big enough*)
seqlen:=maxseqlen
end
else
blockread(rfile,sarr,seqlen);
if ioresult<>0 then exit;
blockread(rfile,tempname,namelen); (*was 11 in older versions now is 65*)
name:=copy(tempname,1,namelen);
if ioresult<>0 then exit;
blockread(rfile,linesum,6);
if ioresult<>0 then exit;
blockread(rfile,start,6);
if ioresult<>0 then exit;
blockread(rfile,kind,1);
if namelen=11
then case kind of
'P':kind:='T'; 'S':kind:='P';
'A':kind:='A'; else kind:='N'
end;
if ioresult<>0 then exit;
blockread(rfile,numoff,1);
if ioresult<>0 then exit;
blockread(rfile,reve,1);
if ioresult<>0 then exit;
ierr:=0
end
(*$i+*)
end; (*getrecord*)
BEGIN (*restore*)
intry:=0; namelen:=65;
(*$i-*)
repeat (*until ioerr=0*)
(*Get file name*)
flash;
write(output,'RESTORE ... What is the name of the Saved file? .... <RET> to abort');
gotoxy(1,2); write(output,'>'); clreol; readln(iname);
if iname='' then begin insrept; exit end;
(*OPEN file HERE..........................v-INDICATES READ RECORDS=1 BYTE*)
assign(rfile,iname); reset(rfile,1);
ierr:=ioresult; intry:=intry+1;
if ierr<>0 then begin
mestr:='** FILE NOT FOUND **';
emesg
end
until (ierr=0) or (intry>2);
(*Get here if valid file found and successfully opened*)
(*$i+*)
if intry>2
then
begin
mestr:='** Look you''ve had three tries now and you haven''t hit one yet. I quit !!!';
emesg; exit
end;
(*$i-*)
if sizeof(rfile)<=0 then exit;
(*check for logo stamp in data file*)
blockread(rfile,stamp,1);
if ioresult<>0 then exit;
{ if stamp<>logo then (*logo is currently char(254)*)}
if not (stamp in [logo,#253]) then
begin (*now always bailout, as advertised*)
close(rfile);
mestr:='WARNING: That file''s format is not correct! If possible, resave it immediately';
emesg; exit
end;
(*Have to determine how many sequences before reading sequence records*)
blockread(rfile,rseq,2);
(*Stuff here is to avoid trying to read more sequences than there
are facilities for 21 in early versions, 46 in next version.
It takes into account the number of sequences already in play (nseq)
*)
if ioresult<>0 then exit;
if ( (nseq+rseq) > maxseqs )
then
if ( (nseq>1) or ( (nseq=1) and (spnt[1]^.seqlen>1)) )
then begin
mestr:='There are too many sequences to restore that file';
emesg; exit
end;
rs:=0;
(*also check to see if there's one empty sequence-startup condition,
if so, get rid of it*)
if ((nseq=1) and (spnt[1]^.seqlen=1))
then begin dispose(spnt[nseq]); nseq:=0; rs:=1 end;
(*Is there enough memory for a all of the sequences?');
if not enuffroom(rseq-1)
then
begin
mestr:='There''s not enough memory to restore that file.';
fadeout; exit
end;
rs:=nseq;
(*Now read those sequece records*)
for i:=1 to rseq do
begin
if enuffroom(1)
then begin
inc(rs); new(spnt[rs]);
getrecord (*set ierr=0 when successful*)
end
else begin
mestr:='NOT enough memory .... ABORTING';
fadeout; exit
end;
if ierr<>0 then
begin
mestr:='I/O error, is the file really a Saved file? Operation Aborted.';
fadeout; exit
end
end; (*end of reading*)
close(rfile);
if (ioresult<>0) then
begin
mestr:='I/O error on file close. Command aborted.';
emesg; if nseq=0 then begin seqno:=1; create end; exit
end;
(*$i+*)
(*ETC*)
end; (*restore*)